<?php

namespace Upfor\UpforPHP\Library;

/**
 * Math util
 */
class Math {

    /**
     * Is a integer
     *
     * @see    http://php.net/manual/zh/function.is-numeric.php#118080
     * @param  integer $val
     * @return boolean
     */
    public static function isInt($val) {
        $val = strval($val);
        if ($val{0} == '-') {
            $val = str_replace('-', '', $val);
        }

        if (ctype_digit($val)) {
            if ($val === (string) 0) {
                return true;
            } elseif (ltrim($val, '0') === $val) {
                return true;
            }
        }

        return false;
    }

    /**
     * Is numeric
     *
     * @see    http://php.net/manual/zh/function.is-numeric.php#118080
     * @param  integer|float $val
     * @return boolean
     */
    public static function isNumeric($val) {
        if (is_numeric($val) && floor($val) == $val) {
            if ((string) $val === (string) 0) {
                return true;
            } elseif (ltrim((string) $val, '0') === (string) $val) {
                return true;
            }
        }

        return false;
    }

    /**
     * Is a natural number
     *
     * @param  integer $val
     * @param  boolean $acceptZero
     * @return boolean
     */
    public static function isNatural($val, $acceptZero = false) {
        $return = ((string) $val === (string) (int) $val);
        if ($acceptZero) {
            $base = 0;
        } else {
            $base = 1;
        }

        if ($return && intval($val) < $base) {
            $return = false;
        }

        return $return;
    }

    /**
     * Is a odd number
     *
     * @param  integer $num
     * @return boolean
     */
    public static function isOdd($num) {
        return (is_numeric($num) & ($num & 1));
    }

    /**
     * Is a even number
     *
     * @param  integer $num
     * @return boolean
     */
    public static function isEven($num) {
        return (is_numeric($num) & (!($num & 1)));
    }

    /**
     * Ordinal number
     *
     * @see    http://php.net/manual/zh/function.is-numeric.php#99876
     * @param  integer $num
     * @return false|string
     */
    public static function ordinal($num) {
        // a temporary value we can change, and keep the original value.
        $origin = $num;

        // suffixes = 0th, 1st, 2nd, third == zeroth, first, second, third
        $suffixes = array('th', 'st', 'nd', 'rd');

        // if input just so happens to be a string, we check to make sure it
        // still holds a numeric value and only acquire the last 2 numbers.
        // if it's not a string, nor an integer, we freak out and say no.
        if (!is_int($origin)) {
            if (ctype_digit($origin)) {
                $origin = (int) substr($origin, -2, 2);
            } else {
                return false;
            }
        }

        // basically, if $o is between 11 and 19, we use 'th'
        // otherwise we use the last digit and if it's over
        // 4 then we use 0 (for the $s array index).
        return ($num . $suffixes[($origin % 100 > 10 && $origin % 100 < 20) ? 0 : ($origin % 10 < 4 ? $origin % 10 : 0)]);
    }

}